/* timer1.c
 * 使用timer1的输入被捉单元来检测两个液滴之前的时间差
 */

#include "config.h"
#ifdef TIMER1_H_INCLUDED
static pMsgBox notice = NULL;
static Message msg;
const Message * const timer1Caputre = &msg;
static UINT32 captureInterval = 0;
static UINT16 ovfcnt = 0;

/* 初始化T/C1，使之以普通模式计数，输入捕捉下降沿，使能 噪声抑制 */
void timer1Init( void )
{
	timer1Stop();
	TCCR1A = 0x00;
	TCCR1C = 0x00;
	CBI( ACSR, ACIC );
	SBI( PORTD, PD4 );//使能上拉电阻
	CBI( DDRD, PD4 ); //将输入被捉引脚置为输入
	SBI( TIMSK, TOIE1 );
}

/* 捕获开始  */
void timer1Start( uint8_t ck )
{
	uint8_t sr = SREG;
	cli();
	ovfcnt = 0;
	TCNT1 = 0;
	SBI( TIFR, ICF1 );
	SBI( TIMSK, TICIE1 );
	TCCR1B = ck | ICP1CONF;
	SREG = sr;
}

void timer1SetNotice( pMsgBox mb )
{
	notice = mb;
}

inline UINT32 timer1GetCount( void )
{
	return captureInterval;
}

/* 由于单次的捕获没有意义，所以不会自动停止捕获 */
DEF_OSISR( TIMER1_CAPT_vect )
{
	enterKernel();
	uint16_t *ptr = (uint16_t *) &captureInterval;
	ptr[0] = ICR1;
	ptr[1] = ovfcnt;
	/* 第二个表达式限制第二次捕获不能小于上一次的2分之1 */
	if( notice != NULL ){
		sendMsgInt( notice, &msg );
	}
	ovfcnt = 0;
	TCNT1 = 0;

	enterTask();
}

DEF_OSISR( TIMER1_OVF_vect )
{
	enterKernel();
	++ ovfcnt;
	enterTask();
}

#endif
